package com.ruoyi.management.service.impl;

import com.github.pagehelper.PageHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.management.dao.mapper.AmmeterMapper;
import com.ruoyi.management.dao.mapper.BillingMapper;
import com.ruoyi.management.dao.mapper.EnergyMapper;
import com.ruoyi.management.mqtt.MqttContext;
import com.ruoyi.management.pojo.dto.DbDayDto;
import com.ruoyi.management.pojo.dto.DbInfoDto;
import com.ruoyi.management.pojo.entity.AirConditioningParam;
import com.ruoyi.management.pojo.entity.KhbhDbbh;
import com.ruoyi.management.pojo.param.CheckParam;
import com.ruoyi.management.pojo.param.ZtParam;
import com.ruoyi.management.pojo.po.AmmeterResultPo;
import com.ruoyi.management.pojo.po.CheckPO;
import com.ruoyi.management.pojo.po.MouthReadPO;
import com.ruoyi.management.pojo.po.QldbzymxPO;
import com.ruoyi.management.pojo.vo.*;
import com.ruoyi.management.service.DbDayService;
import com.ruoyi.management.service.EnergyService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

@Slf4j
@Service
public class EnergyImpl implements EnergyService {

    @Autowired
    private EnergyMapper energyMapper;

    @Autowired
    private BillingMapper billingMapper;

    @Autowired
    private BillingImpl billingImpl;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private MqttContext mqttContext;

    @Autowired
    private DbDayService dbDayService;

    @Autowired
    private AmmeterMapper ammeterMapper;

    @Override
    public Map<String, Object> readData(String dbbh, String qymc, Integer pageNum, Integer pageSize, String...params) {
        Map<String, Object> result = new HashMap<>();
        log.info("开始：获取电表实时数据，dbbh: {}, qymc: {}", dbbh, qymc);

        // 1. 构建Redis键模式
        String redisKeyPattern = "ammeter:result:*";
        if (dbbh != null && !dbbh.isEmpty()) {
            redisKeyPattern = "ammeter:result:*" + dbbh + "*";
        }

        // 2. 扫描Redis中匹配的电表数据键
        ScanOptions options = ScanOptions.scanOptions().match(redisKeyPattern).build();
        Cursor<byte[]> scan = mqttContext.getRedisTemplate()
                .getConnectionFactory()
                .getConnection()
                .scan(options);

        // 3. 按电表编号分组存储数据
        Map<String, List<AmmeterResultPo>> groupedByDbbh = new HashMap<>();

        while (scan.hasNext()) {
            String redisKey = new String(scan.next());
            AmmeterResultPo resultPo = mqttContext.getRedisTemplate().opsForValue().get(redisKey);

            if (resultPo != null && (dbbh == null || dbbh.isEmpty() || resultPo.getDbbh().equals(dbbh))) {
                groupedByDbbh.computeIfAbsent(
                        resultPo.getDbbh(),
                        k -> new ArrayList<>()
                ).add(resultPo);
            }
        }

        // 4. 获取当前时间作为参考点
        long now = System.currentTimeMillis();
        List<AmmeterTimeVO> allResults = new ArrayList<>();

        // 5. 找出每个电表最接近当前时间的数据并转换为VO
        groupedByDbbh.forEach((currentDbbh, dataList) -> {
            dataList.stream()
                    .min(Comparator.comparingLong(po ->
                            Math.abs(po.getTimestamp().getTime() - now)
                    ))
                    .ifPresent(po -> {
                        AmmeterTimeVO vo = energyMapper.selectAmmeterTimeVO(po.getDbbh());

                        // 添加企业名称过滤条件
                        if (qymc == null || qymc.isEmpty() || (vo.getQymc() != null && vo.getQymc().equals(qymc))) {
                            // 当前账号非admin账号，只能查询所属载体的信息
                            if (ObjectUtils.isNotEmpty(params) && !"null".equals(params[0]) && !"1".equals(params[0])) {
                                ZtParam ztParam = new ZtParam();
                                ztParam.setTgszt(params[0]);
                                List<ZTVO> ztvos = ammeterMapper.selectZtByNra(ztParam);
                                if (CollectionUtils.isNotEmpty(ztvos)) {
                                    String nr = ztvos.get(0).getNr();
                                    if (ObjectUtils.isNotEmpty(vo) && StringUtils.isNotBlank(vo.getZt())) {
                                        if (!nr.equals(vo.getZt())) {
                                            return;
                                        }
                                    }
                                }
                            }

                            BigDecimal mouthRead = energyMapper.selectMouthUsed(po.getDbbh()) == null ? BigDecimal.ZERO : energyMapper.selectMouthUsed(po.getDbbh());
                            BigDecimal monthUsed = po.getTotalPower().subtract(mouthRead);
                            vo.setUa(po.getVoltageA());
                            vo.setUb(po.getVoltageB());
                            vo.setUc(po.getVoltageC());
                            vo.setIa(po.getCurrentA());
                            vo.setIb(po.getCurrentB());
                            vo.setIc(po.getCurrentC());
                            vo.setP(po.getTotalActivePower());
                            vo.setQ(po.getTotalReactivePower());
                            vo.setDbz(po.getTotalPower());
                            vo.setMonthUsed(monthUsed);
                            allResults.add(vo);
                        }
                    });
        });

        // 6. 分页处理
        if (pageNum != null && pageSize != null) {
            int start = (pageNum - 1) * pageSize;
            int end = Math.min(start + pageSize, allResults.size());
            if (start > allResults.size()) {
                return null;
            }
            result.put("data", allResults.subList(start, end));
        }

        result.put("total", allResults.size());
        return result;
    }

    @Override
    public List<EneryVO> Ccompute(String dbbh, String qymc, Date date, String zt) {
        return energyMapper.dayEnergy(dbbh, qymc,date, zt);
    }



    @Override
    public List<EneryVO> selectmouth(String dbbh, String qymc, Date month, String zt) {
        ZoneId zone = ZoneId.systemDefault();
        if (isCurrentMonth(month, zone)) {
        List<EneryVO> khbhDbbhs = energyMapper.selectQldb(dbbh,qymc,zt); // 查询 qldbzymx 的基础信息
            List<EneryVO> result = new ArrayList<>();

            for (EneryVO item : khbhDbbhs) {
                String currentDbbh = item.getDbbh();
                if (currentDbbh == null) continue;

                // 查询 currentReading
                Map<String, Object> dbdata = energyMapper.getLastDbDataByDbbh(currentDbbh);
                BigDecimal currentReading = dbdata != null && dbdata.containsKey("total_power") ?
                        new BigDecimal(dbdata.get("total_power").toString()) : BigDecimal.ZERO;

                // 查询 lastReading
                BigDecimal lastReading = energyMapper.getMouthReadByDbbhAndMonth(currentDbbh, month);
                lastReading = lastReading != null ? lastReading : BigDecimal.ZERO;

                // 计算 used
                BigDecimal used = currentReading.subtract(lastReading);

                // 设置到 VO
                item.setCurrentReading(currentReading);
                item.setLastReading(lastReading);
                item.setUsed(used);
                item.setMonth(new SimpleDateFormat("yyyy-MM").format(month)); // 设置月份
                result.add(item);
            }
            return result;
        }
        List<EneryVO> result= energyMapper.selectlastmouth(dbbh, qymc, month, zt);
        // 遍历 result 设置 month = nf-yf
        for (EneryVO item : result) {
            if (item.getNf() != null && item.getYf() != null) {
                item.setMonth(String.format("%d-%02d", item.getNf(), item.getYf()));
            }
        }

        return result; // 避免返回 null
    }

    @Override
    public List<Map<String, Object>> monthDayEnery(String dbbh, Date month) {
        List<Map<String, Object>> list = energyMapper.monthDayEnery(dbbh, month);
        return list;
    }


    /**
     * 年度电量
     * @param dbInfoDto 电表信息
     * @return 电量
     */
    @Override
    public List<EneryVO> selectYearEnergy(DbInfoDto dbInfoDto) {
        // 校验年份
        if (dbInfoDto.getYear() == null) {
            return new ArrayList<>();
        } else {
            if (dbInfoDto.getYear().length() > 4) {
                dbInfoDto.setYear(dbInfoDto.getYear().substring(0, 4));
            }
        }

        // 上一年
        String lastYear = String.valueOf(Integer.parseInt(dbInfoDto.getYear()) - 1);
        dbInfoDto.setLastYear(lastYear);


        // 查询当前用户所属的载体项目的电表编号
        List<EneryVO> dbBhs = energyMapper.selectDbBh(dbInfoDto);
        if (CollectionUtils.isNotEmpty(dbBhs)) {
            dbBhs.forEach(item -> {
                item.setNf(Integer.valueOf(dbInfoDto.getYear())); // 设置年份
                dbInfoDto.setDbbh(item.getDbbh()); // 设置电表编号

                /* 本年 */
                // 查询该编号电表的年度数据
                List<MouthReadPO> energyVOS = energyMapper.selectYearEnergy(dbInfoDto);
                // 如果表中有年度电量，直接绑定
                if (CollectionUtils.isNotEmpty(energyVOS)
                        && energyVOS.get(0).getYearRead() != null
                        && energyVOS.get(0).getYearRead().compareTo(BigDecimal.ZERO) != 0) {
                    item.setCurrentReading(energyVOS.get(0).getYearRead());
                } else { // 没有电量则统计日电量累加
                    DbDayDto dbDayDto = new DbDayDto();
                    dbDayDto.setDbbh(item.getDbbh()); // 设置电表编号
                    dbDayDto.setStartTime(LocalDateTime.parse(dbInfoDto.getYear() + "-01-01 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    dbDayDto.setEndTime(LocalDateTime.parse(dbInfoDto.getYear() + "-12-31 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    List<DbDayVo> dbDayVos = dbDayService.selectDbDay(dbDayDto); // 查询该编号电表的日数据
                    if (CollectionUtils.isNotEmpty(dbDayVos)) {
                        final BigDecimal[] sum = {BigDecimal.ZERO};
                        dbDayVos.forEach(dbDayVo -> {
                            sum[0] = sum[0].add(dbDayVo.getTotalPower());
                        });
                        item.setCurrentReading(sum[0]); // 绑定本年电量
                    } else {
                        item.setCurrentReading(BigDecimal.ZERO);
                    }
                }

                /* 上一年 */
                // 查询该编号电表的年度数据
                List<MouthReadPO> lastYearEnergyVOS = energyMapper.selectLastYearEnergy(dbInfoDto);
                // 如果表中有年度电量，直接绑定
                if (CollectionUtils.isNotEmpty(lastYearEnergyVOS)
                        && lastYearEnergyVOS.get(0).getYearRead() != null
                        && lastYearEnergyVOS.get(0).getYearRead().compareTo(BigDecimal.ZERO) != 0) {
                    item.setCurrentReading(lastYearEnergyVOS.get(0).getYearRead());
                } else { // 没有电量则统计日电量累加
                    DbDayDto dbDayDto = new DbDayDto();
                    dbDayDto.setDbbh(item.getDbbh()); // 设置电表编号
                    dbDayDto.setStartTime(LocalDateTime.parse(dbInfoDto.getLastYear() + "-01-01 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    dbDayDto.setEndTime(LocalDateTime.parse(dbInfoDto.getLastYear() + "-12-31 23:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                    List<DbDayVo> dbDayVos = dbDayService.selectDbDay(dbDayDto); // 查询该编号电表的日数据
                    if (CollectionUtils.isNotEmpty(dbDayVos)) {
                        final BigDecimal[] sum = {BigDecimal.ZERO};
                        dbDayVos.forEach(dbDayVo -> {
                            sum[0] = sum[0].add(dbDayVo.getTotalPower());
                        });
                        item.setLastReading(sum[0]); // 绑定上年电量
                    } else {
                        item.setLastReading(BigDecimal.ZERO);
                    }

                }
            });
        }

        return dbBhs;
    }

    @Override
    public List<Map<String, Object>> yearMonthEnery(String dbbh, String year) {
        Integer date=Integer.parseInt(year.toString());
        List<Map<String, Object>> list = energyMapper.yearMonthEnery(dbbh,date);
        return list;
    }


    @Override
    public List<CheckVO> checkEnergyList(String year, String zt,String tgszt) {
        String[] values = tgszt.split(",");
        if (year!=null){
            Integer date=Integer.parseInt(year.toString());
            List<CheckVO> list = energyMapper.checkEnergyList(date,zt,values);
            return list;
        }
        Integer date = LocalDate.now().getYear();
        List<CheckVO> list = energyMapper.checkEnergyList(date,zt,values);
        return list;
    }

    @Override
    public BigDecimal getZtMonthEnery(LocalDate month, String zt) {
        List<KhbhDbbh> khbhList = energyMapper.selectQldbzymx1(month,zt);
        BigDecimal totalZzdl = BigDecimal.ZERO;
        for (KhbhDbbh kd : khbhList) {
            List<BillingVO> result = Ccompute11(month, kd);
            // 对 result 中的 zzdl 求和
            for (BillingVO vo : result) {
                BigDecimal zzdl = vo.getZzdl();
                if (zzdl != null) {
                    totalZzdl = totalZzdl.add(zzdl);
                }
            }
        }
        return totalZzdl;
    }

    @Override
    public Boolean checkEnergy(CheckParam checkParam) {
        CheckPO checkPO = new CheckPO();
        checkPO.setZt(checkParam.getZt());
        checkPO.setCapacityCharge(checkParam.getCapacityCharge());
        BigDecimal checkValue = checkParam.getCheckValue();
        if (checkParam.getCheckValue() != null && checkParam.getZtValue() != null) {
            // 减法运算并设置精度和舍入模式
            checkValue = checkParam.getCheckValue()
                    .subtract(checkParam.getZtValue())
                    .setScale(2, RoundingMode.HALF_UP); // 保留2位小数，四舍五入
        }
        checkPO.setCheckValue(checkValue);
        checkPO.setZtValue(checkParam.getZtValue());

        if (ObjectUtils.isNotEmpty(checkParam.getZtValue())) {
            // 修改后正确代码：
            BigDecimal ratio = checkValue.divide(
                    checkParam.getZtValue(),
                    1, // 保留2位小数
                    BigDecimal.ROUND_HALF_UP // 四舍五入方式
            );
            checkPO.setRatio(ratio);
        }
        String monthStr = checkParam.getMonth();
// 使用 YearMonth 来解析 yyyy-MM 格式
        YearMonth yearMonth = YearMonth.parse(monthStr, DateTimeFormatter.ofPattern("yyyy-MM"));
// 转换为 LocalDate（取当月第一天）
        LocalDate localDate = yearMonth.atDay(1);
// 再转成 Date
        Date date = Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
        checkPO.setNf(yearMonth.getYear());       // 年份
        checkPO.setYf(yearMonth.getMonthValue()); // 月份
        checkPO.setTimestamp(new Date());
        checkPO.setTname(checkParam.getTname());
        Boolean a=energyMapper.checkEnergy(checkPO);
        Boolean b=energyMapper.checkdf(checkPO);
        return a;

    }

    @Override
    public List<Map<String, Object>> dayEnergy(String dbbh, Date date) {
        // 1. 计算当天的时间范围
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        Date startOfDay = calendar.getTime();

        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        Date endOfDay = calendar.getTime();
        // 2. 扫描Redis数据
        String keyPattern = "ammeter:result:" + dbbh + ":*";
        ScanOptions options = ScanOptions.scanOptions().match(keyPattern).build();
        List<AmmeterResultPo> rawResults = new ArrayList<>();
        try (Cursor<byte[]> scan = mqttContext.getRedisTemplate()
                .getConnectionFactory()
                .getConnection()
                .scan(options)) {
            while (scan.hasNext()) {
                // 过滤逻辑...
                String redisKey = new String(scan.next());
                AmmeterResultPo resultPo = mqttContext.getRedisTemplate().opsForValue().get(redisKey);
                if (resultPo != null &&
                        !resultPo.getTimestamp().before(startOfDay) &&
                        !resultPo.getTimestamp().after(endOfDay)) {
                    rawResults.add(resultPo);
                }
            }
        }

        // 如果没有数据，直接返回空的24小时数据
        if (rawResults.isEmpty()) {
            return createEmptyHourlyData();
        }

        // 3. 按时间戳排序
        rawResults.sort(Comparator.comparing(AmmeterResultPo::getTimestamp));

        // 4. 按小时分组，获取每小时最后一条记录
        Map<Integer, AmmeterResultPo> hourlyData = new TreeMap<>();
        for (AmmeterResultPo po : rawResults) {
            Calendar poCalendar = Calendar.getInstance();
            poCalendar.setTime(po.getTimestamp());
            int hour = poCalendar.get(Calendar.HOUR_OF_DAY);

            // 只保留每小时最后一条记录
            if (!hourlyData.containsKey(hour) ||
                    po.getTimestamp().after(hourlyData.get(hour).getTimestamp())) {
                hourlyData.put(hour, po);
            }
        }

        // 5. 计算每小时用电量
        List<Map<String, Object>> result = new ArrayList<>();
        BigDecimal previousValue = null; // 初始化为null，等待第一个有效数据

        for (int hour = 0; hour < 24; hour++) {
            Map<String, Object> hourData = new HashMap<>();
            hourData.put("hour", hour + ":00");

            AmmeterResultPo currentHourPo = hourlyData.get(hour);
            BigDecimal hourlyUsed = BigDecimal.ZERO;

            if (currentHourPo != null) {
                BigDecimal currentValue = currentHourPo.getTotalPower();

                // 如果是第一个有效数据，不计算差值，只设置基准值
                if (previousValue == null) {
                    previousValue = currentValue;
                    hourlyUsed = BigDecimal.ZERO;
                } else {
                    // 计算当前小时用电量
                    hourlyUsed = currentValue.subtract(previousValue);
                    // 确保用电量不为负数
                    if (hourlyUsed.compareTo(BigDecimal.ZERO) < 0) {
                        hourlyUsed = BigDecimal.ZERO;
                    }
                    previousValue = currentValue;
                }
            } else if (previousValue != null) {
                // 如果当前小时没有数据，但之前有数据，用电量设为0
                hourlyUsed = BigDecimal.ZERO;
            }

            hourData.put("used", hourlyUsed.setScale(2, RoundingMode.HALF_UP));
            System.out.println(hourData);
            result.add(hourData);
        }

        System.out.println("Hourly consumption data: " + result);
        return result;
    }

    // 创建空的24小时数据
    private List<Map<String, Object>> createEmptyHourlyData() {
        List<Map<String, Object>> emptyData = new ArrayList<>();
        for (int hour = 0; hour < 24; hour++) {
            Map<String, Object> hourData = new HashMap<>();
            hourData.put("hour", hour + ":00");
            hourData.put("used", BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP));
            emptyData.add(hourData);
        }
        return emptyData;
    }



    @Override
    public Boolean airConditioning(List<AirConditioningParam> param) {
        for (AirConditioningParam bill : param) {
            // 处理单条数据（如存入数据库）

        }
        return null;
    }

    private void ensureFullDayDataWithCalculation(List<Map<String, Object>> data) {
        // 1. 创建24小时的完整时间列表
        List<String> fullHours = IntStream.range(0, 24)
                .mapToObj(h -> String.format("%d:00", h))
                .collect(Collectors.toList());

        // 2. 找出已存在的小时数据
        Set<String> existingHours = data.stream()
                .map(map -> (String) map.get("hour"))
                .collect(Collectors.toSet());

        // 3. 补全缺失的小时数据（保持计算连续性）
        BigDecimal lastValidValue = BigDecimal.ZERO;
        List<Map<String, Object>> completeData = new ArrayList<>();

        for (String hour : fullHours) {
            Optional<Map<String, Object>> existingHour = data.stream()
                    .filter(map -> hour.equals(map.get("hour")))
                    .findFirst();

            if (existingHour.isPresent()) {
                completeData.add(existingHour.get());
                lastValidValue = ((BigDecimal) existingHour.get().get("used"));
            } else {
                Map<String, Object> missingHour = new HashMap<>();
                missingHour.put("hour", hour);
                // 缺失的小时用电量为0
                missingHour.put("used", BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP));
                completeData.add(missingHour);
                // 不更新lastValidValue，保持之前的值
            }
        }

        // 4. 替换原始数据
        data.clear();
        data.addAll(completeData);
    }


    public List<BillingVO> Ccompute11(LocalDate month,KhbhDbbh kd) {
        List<QldbzymxPO> poList = billingMapper.selectQldbzymx(kd);
        LocalDate now = month;
        List<BillingVO> result = new ArrayList<>();
        for (QldbzymxPO po : poList) {
            result.add(billingImpl.processBilling(po, now));
        }
        return result;
    }

    public boolean isCurrentMonth(Date month, ZoneId zone) {
        if (month == null) return false;
        LocalDate input = month.toInstant().atZone(zone).toLocalDate();
        LocalDate now = LocalDate.now(zone);
        return input.getYear() == now.getYear() && input.getMonth() == now.getMonth();
    }

    /**
     * 通过dbbh获取Redis中电表的最新记录
     * @param dbbh 电表编号
     * @return 最新记录的AmmeterResultPo对象
     */
    public Optional<AmmeterResultPo> getLatestAmmeterRecordByDbbh(String dbbh) {
        if (dbbh == null || dbbh.isEmpty()) {
            log.warn("dbbh不能为空");
            return Optional.empty();
        }

        ScanOptions options = ScanOptions.scanOptions().match("ammeter:result:*" + dbbh + "*").build();
        Cursor<byte[]> scan = mqttContext.getRedisTemplate().getConnectionFactory().getConnection().scan(options);

        List<AmmeterResultPo> records = new ArrayList<>();

        while (scan.hasNext()) {
            byte[] keyBytes = scan.next();
            String redisKey = new String(keyBytes);
            AmmeterResultPo resultPo = mqttContext.getRedisTemplate().opsForValue().get(redisKey);

            if (resultPo != null && dbbh.equals(resultPo.getDbbh())) {
                records.add(resultPo);
            }
        }

        // 返回时间上最接近当前时间的记录
        return records.stream()
                .min(Comparator.comparingLong(po -> Math.abs(po.getTimestamp().getTime() - System.currentTimeMillis())));
    }

    // 修改 shiftUsedData 方法，使其返回处理后的列表
    public static List<Map<String, Object>> shiftUsedData(List<Map<String, Object>> dataList) {
        if (dataList == null || dataList.isEmpty()) return dataList;

        // 保存第一个 used 值
        Object firstUsed = dataList.get(0).get("used");

        // 从第 0 到倒数第二个元素，把 used 替换为下一个的 used
        for (int i = 0; i < dataList.size() - 1; i++) {
            Object nextUsed = dataList.get(i + 1).get("used");
            dataList.get(i).put("used", nextUsed);
        }

        // 最后一个元素设置为 0
        dataList.get(dataList.size() - 1).put("used", BigDecimal.ZERO);

        return dataList;
    }

    public Map<String, String> getLatestDataForEachDbbh() {
        // 获取所有 ammeter:result:* 的键
        Set<String> keys = stringRedisTemplate.keys("ammeter:result:*");

        // 用于存储每个 dbbh 的最新数据
        Map<String, String> latestData = new HashMap<>();

        // 临时存储每个 dbbh 的所有日期键
        Map<String, List<String>> dbbhToDateKeys = new HashMap<>();

        // 遍历所有键，分类到每个 dbbh 下
        for (String key : keys) {
            // 解析键，得到 dbbh 和 date
            String[] parts = key.split(":");
            if (parts.length == 4) {
                String dbbh = parts[2];
                String dateStr = parts[3];

                // 将日期字符串转换为 LocalDateTime
                LocalDateTime dateTime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("EEE MMM dd HH", Locale.US));

                // 将键按 dbbh 分类
                dbbhToDateKeys.computeIfAbsent(dbbh, k -> new ArrayList<>()).add(key);
            }
        }

        // 对每个 dbbh，找到最新的日期键并获取其值
        for (Map.Entry<String, List<String>> entry : dbbhToDateKeys.entrySet()) {
            String dbbh = entry.getKey();
            List<String> dateKeys = entry.getValue();
            // 按日期排序，找到最新的键
            dateKeys.sort(Comparator.comparing(s -> LocalDateTime.parse(s.split(":")[3], DateTimeFormatter.ofPattern("EEE MMM dd HH", Locale.US))));
            String latestKey = dateKeys.get(dateKeys.size() - 1);
            // 获取最新键的值
            String value = stringRedisTemplate.opsForValue().get(latestKey);
            latestData.put(dbbh, value);
        }
        return latestData;
    }

}


